package org.opens.javaskill.design;

/**
 * 说明:
 *      1. 结构型模式-适配器模式的demo.
 *      2. 熟悉该模式之后, 会发现这个模式的用途确实是在升级老api支持新功能之上.
 *          - 这种设计模式可以保证在尽量少的侵入原代码的情况下使老api支持新功能; 虽然这样可以实现, 但是书上说如果项目规模小, 重构是更好
 *          的做法.
 * 引申:
 *      1. 感觉使用工厂模式来替代这个模式更好.
 *          - 每增加一个播放类型, 加一个相应的接口功能实现类, 然后工厂来生产播放对象.
 */
public class AdapterPatternPattern {

    /**
     * 输出:
     *      播放了mp3文件:s1.mp3
     *      播放了pcm文件: s2.pcm
     *      播放了mp4文件: s1.mp4
     *      java.lang.RuntimeException: 不支持的文件类型
     *      	at org.opens.javaskill.design.AudioPlayer.play(AdapterPatternDemo.java:96)
     *      	at org.opens.javaskill.design.AdapterPatternDemo.main(AdapterPatternDemo.java:11)
     */
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();
        audioPlayer.play("mp3", "s1.mp3");
        audioPlayer.play("pcm", "s2.pcm");
        audioPlayer.play("mp4", "s1.mp4");
        try {
            audioPlayer.play("m3u8", "s1.m3u8");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

interface MediaPlayer {

    public void play(String fileType, String fileName);

}

interface AdvancedMediaPlayer {

    public void playPcm(String fileName);

    public void playMp4(String fileName);

}

class PcmPlayer implements AdvancedMediaPlayer {

    @Override
    public void playPcm(String fileName) {
        System.out.println("播放了pcm文件: " + fileName);
    }

    @Override
    public void playMp4(String fileName) {
        throw new RuntimeException("不支持的操作");
    }

}

class Mp4Player implements AdvancedMediaPlayer {

    @Override
    public void playPcm(String fileName) {
        throw new RuntimeException("不支持的操作");
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("播放了mp4文件: " + fileName);
    }

}

class MediaAdapter implements MediaPlayer {

    private AdvancedMediaPlayer advancedMediaPlayer;

    public MediaAdapter(String fileType) {
        if("pcm".equals(fileType)) {
            this.advancedMediaPlayer = new PcmPlayer();
        } else if("mp4".equals(fileType)) {
            this.advancedMediaPlayer = new Mp4Player();
        }
    }

    @Override
    public void play(String fileType, String fileName) {
        if("pcm".equals(fileType)) {
            advancedMediaPlayer.playPcm(fileName);
        } else if("mp4".equals(fileType)) {
            advancedMediaPlayer.playMp4(fileName);
        } else {
            throw new RuntimeException("不支持的文件类型");
        }
    }

}

class AudioPlayer implements MediaPlayer {

    @Override
    public void play(String fileType, String fileName) {
        if("mp3".equals(fileType)) {
            System.out.println("播放了mp3文件:" + fileName);
        } else if("pcm".equals(fileType) || "mp4".equals(fileType)) {
            MediaAdapter mediaAdapter = new MediaAdapter(fileType);
            mediaAdapter.play(fileType, fileName);
        } else {
            throw new RuntimeException("不支持的文件类型");
        }
    }

}